package cn.xcstudenth.myapplication.texviewutils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LevelListDrawable;
import android.text.Html;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.lang.ref.WeakReference;

import cn.xcstudenth.myapplication.AppComplication;
import cn.xcstudenth.myapplication.ConstantUtils;
import cn.xcstudenth.myapplication.R;


/**
 * Created by 赵航 on 2020/6/5.
 * WeChat: zhao--hang--
 */
public class HtmlImageGetter implements Html.ImageGetter {

    WeakReference<TextView> mTextViewReference;//设置这个类，可以及时回收内存
    Context                 mContext;
    private Drawable empty;
    private int      mDayOrNight = ConstantUtils.ZERO;//默认白天模式

    public HtmlImageGetter(TextView textView, int dayOrNight) {
        this.mContext           = AppComplication.mContext;
        this.mTextViewReference = new WeakReference<TextView>(textView);
        this.mDayOrNight        = dayOrNight;

    }

    @Override
    public Drawable getDrawable(final String source) {
        //设置等级
        LevelListDrawable mDrawable = new LevelListDrawable();
        final WeakReference<LevelListDrawable> mURLDrawableReference =
                new WeakReference<LevelListDrawable>(mDrawable);
        //判断是不是公式图
        if (source == null) {
            return null;
        }
        if (source.contains(ConstantUtils.FORMULAS)) {
            empty = mContext.getResources().getDrawable(
                    R.mipmap.html_no_net_img_small);
        } else {
            empty = mContext.getResources().getDrawable(
                    R.mipmap.html_no_net_img);
        }
        if (mURLDrawableReference.get() != null)
            mURLDrawableReference.get().addLevel(0, 0, empty);
        if (mURLDrawableReference.get() != null)
            mURLDrawableReference.get().setBounds(0, 0, empty.getIntrinsicWidth(),
                    empty.getIntrinsicHeight());

        final Bitmap[] mBitmap = {null};
        //.asBitmap()后.placeholder() 占位图无效果
        String newSoure;
        if (source.contains(ConstantUtils.FONTSIZE)) {
            //对于公式图，仅仅需要加载一遍即可，也就是把每张图片设置成一个固定的死网址
            newSoure = source.replaceAll(ConstantUtils.FONTSIZED,
                    ConstantUtils.FONTSIZE + ConstantUtils.TEXTSIZMIDLE);
        } else {
            newSoure = source;
        }
        Glide.with(AppComplication.mContext).asBitmap().apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.ALL)).load(newSoure).into(new SimpleTarget<Bitmap>() {
            @Override
            public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<?
                                super Bitmap> transition) {
                mBitmap[0] = resource;

                //TODO:在子线程中压缩图片
                ThreadUtils.executeNewSubThread(new Runnable() {
                    @Override
                    public void run() {
                        if (mBitmap[0] == null) {
                            return;
                        }
                        //压缩前后，图片的宽度不变
                        boolean isPng = false;//记录当前图片的类型
                        if (source != null && source.contains("png")) {
                            isPng = true;
                        } else {
                            isPng = false;
                        }
                        try {
                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
                            if (isPng) {
                                //质量压缩方法，这里100表示不压缩，把数据存放到baos中,
                                mBitmap[0].compress(Bitmap.CompressFormat.PNG, 100, baos);
                            } else {
                                mBitmap[0].compress(Bitmap.CompressFormat.JPEG, 100, baos);
                            }

                            int options = 100;
                            while (baos.toByteArray().length / 1024 > 20) {
                                //循环判断如果压缩后图片是否大于20kb,大于继续压缩
                                baos.reset();//重置baos即清空baos
                                if (isPng) {
                                    mBitmap[0].compress(Bitmap.CompressFormat.JPEG,
                                            options, baos);
                                    //这里压缩options
                                    // %，把压缩后的数据存放到baos中
                                } else {
                                    mBitmap[0].compress(Bitmap.CompressFormat.PNG,
                                            options, baos);
                                }
                                options -= 2;//每次都减少2
                                if (options < 0) {
                                    break;
                                }
                            }
                            ByteArrayInputStream isBm =
                                    new ByteArrayInputStream(baos.toByteArray());
                            //把压缩后的数据baos存放到ByteArrayInputStream中
                            baos.close();
                            BitmapFactory.Options optionsios = new BitmapFactory.Options();
                            optionsios.inPreferredConfig = Bitmap.Config.ARGB_8888;
                            Rect rect = new Rect();

                            // 数据生成图
                            mBitmap[0] = BitmapFactory.decodeStream(isBm, rect, optionsios);
                            isBm.close();
                            if (mBitmap[0] == null) {
                                return;
                            }
                            BitmapDrawable d          = new BitmapDrawable(mBitmap[0]);
                            int            mOldWidth  = mBitmap[0].getWidth();
                            int            mOldHeight = mBitmap[0].getHeight();
                            if (mURLDrawableReference.get() != null) {
                                if (d == null) {
                                    return;
                                }
                                mURLDrawableReference.get().addLevel(1, 1, d);

                                //获取屏幕的宽度
                                if (AppComplication.mPhoneWith == 0 || AppComplication.mPhoneWith < 0) {
                                    AppComplication.mPhoneWith =PhoneCheckUtils.getScreamWidth();
                                }

                                //根据两边的pading值为15dp，所以30dp为条目的整体宽度
                                int i = PhoneCheckUtils.changeDpToPx(30);

                                if (mOldWidth > AppComplication.mPhoneWith - i) {
                                    float b = (AppComplication.mPhoneWith - i) / mOldWidth;
                                    //采用等比例压缩显示的方法尽心展示
                                    mURLDrawableReference.get().setBounds(0, 0, AppComplication.mPhoneWith - i, (int) (mOldHeight * b));
                                } else {
                                    //当图片文字小于20的时候，按照大图来处理
                                    int b = PhoneCheckUtils.changeDpToPx(20);
                                    if (mOldHeight > b) {
                                        mURLDrawableReference.get().setBounds(0, 0, mOldWidth, mOldHeight);
                                    } else {
                                        float c = b / mOldHeight;
                                        mURLDrawableReference.get().setBounds(0, 0, (int) (mOldWidth * c), b);
                                    }

                                }

                                //如果是夜间模式需要设置一下
                                if (mDayOrNight == ConstantUtils.ONE) {
                                    mURLDrawableReference.get().setAlpha(90);
                                }
                                //设置在最前面显示
                                mURLDrawableReference.get().setLevel(1);

                            }

                            //TODO:在主线程中进行赋值操作
                            ThreadUtils.executeMainThread(new Runnable() {
                                @Override
                                public void run() {
                                    if (mTextViewReference.get() != null) {
                                        mTextViewReference.get().invalidate();
                                        //不加这句显示不出来图片，原因不详
                                        mTextViewReference.get().setText(mTextViewReference.get().getText());
                                    }
                                }
                            });
                        } catch (Exception e) {

                        }


                    }
                });
            }
        });
        return mURLDrawableReference.get();
    }

}
